<?php

namespace App\Logic\Auth;

use App\Component\LogListForm;
use App\Core\BaseCore;
use App\Core\Exception\DefaultException;
use App\Core\Exception\ValidationException;
use App\Core\Output;
use App\Enums\ValidateEnums;
use App\Model\Auth\RoleModel;
use App\Model\UserLogModel;
use App\Model\UserModel;
use App\Util\ArrayHelper;
use App\Util\CommonHelper;
use App\Util\UserIdentityHelper;
use EasySwoole\Component\Di;
use EasySwoole\Component\Singleton;
use EasySwoole\ORM\Exception\Exception;
use EasySwoole\Redis\Redis;
use EasySwoole\RedisPool\RedisPool;
use EasySwoole\Utility\Random;
use EasySwoole\Validate\Validate;
use Throwable;

class UserService extends BaseCore
{

    use Singleton;

    /**
     * 生成密码&密码种子
     * @param $password
     * @return array [密码,密码种子]
     */
    public function getPassword($password)
    {
        $salt = \EasySwoole\Utility\Random::character(9);
        $pwd = CommonHelper::pwdEncrypt($password, $salt);
        return [$pwd, $salt];
    }

    /**
     * 字典数据
     * @param $data
     * @return Output
     * @throws Exception
     * @throws Throwable
     */
    public function getDict() : Output
    {
        $role_dict = (new \App\Model\Auth\RoleModel)->dictList();
        $role_dict = array_column($role_dict, 'name', 'id');
        $result = [
            'type_list'           => ArrayHelper::keyArrayToList(UserModel::getTypeDict()),
            'state_list'          => ArrayHelper::keyArrayToList(UserModel::getStateDict()),
            'role_dict'           => ArrayHelper::keyArrayToList($role_dict),
            'user_list'           => (new UserModel())->userList(UserModel::TYPE_INSIDE),
        ];

        return $this->success($result);
    }

    public function createUser(
        string $username,
        string $phone,
        string $psw,
        int $merchants_id = 0,
        int $warehouse_id = 0
    ){
        $data = [];

        if ( UserModel::getCount(['username'=>$username]) != 0 ){
            throw new ValidationException(ValidateEnums::CHECK_REQUIRED,'该用户名已经注册');
        }

        if ( UserModel::getCount(['phone'=>$phone]) != 0 ){
            throw new ValidationException(ValidateEnums::CHECK_REQUIRED,'该手机号已经注册');
        }

        //生成密码
        list($password, $salt) = self::getPassword($psw);
        $data['password'] = $password;
        $data['salt'] = $salt;

        if (!empty($merchants_id) && !empty($warehouse_id)) {
            $data['type'] = UserModel::TYPE_WAREHOUSE;
            $data['role_id'] = RoleModel::ROLE_WAREHOUSE;
            $data['merchants_id'] = $merchants_id;
            $data['warehouse_id'] = $warehouse_id;
        }elseif (!empty($merchants_id)) {
            $data['type'] = UserModel::TYPE_BUSINESS;
            $data['role_id'] = RoleModel::ROLE_BUSINESS;
            $data['merchants_id'] = $merchants_id;
        }else {
            $data['type'] = UserModel::TYPE_INSIDE;
            $data['role_id'] = RoleModel::ROLE_INSIDE;
        }

        $data['username'] = $username;
        $data['name'] = $username;
        $data['phone'] = $phone;
        $data['state'] = UserModel::ENABLED;

        $res = UserModel::insertData($data);

        return $res->lastQueryResult()->getLastInsertId();
    }

    /**
     * 清空用户缓存
     * @param $id
     * @throws Throwable
     */
    public function delCache($id){
        /** @var Redis $cache */
//        $cache = Di::getInstance()->get("REDIS");
        $cache = RedisPool::defer();
        $cache_key = "userInfoAuth:" . $id;
        $cache->del($cache_key);
    }

    /**
     * 设置使用状态
     * @param $data
     * @return Output
     * @throws DefaultException
     * @throws \EasySwoole\Validate\Exception\Runtime
     */
    public function settingState($data) : Output{
        if (UserIdentityHelper::getType() != UserModel::TYPE_INSIDE) {
            if(UserIdentityHelper::getType() != UserModel::TYPE_BUSINESS) {
                throw new DefaultException('当前账号无暂停账号权限!');
            }
        }
        // 验证规则
        $rules = [
            'ids'        => 'required|notEmpty|isArray',
            'state' => 'required|notEmpty',
        ];

        // 验证字段的别名
        $alias = [
            'ids'        => '用户id',
            'state' => '设置类型',
        ];

        // 组装快速验证
        $validate = Validate::make($rules, [], $alias);

        //操作类型
        $validate->addColumn('state')->inArray([UserModel::ENABLED,UserModel::DISABLED]);

        // 验证结果
        $bool = $validate->validate($data);
        if (!$bool) {
            throw new DefaultException($validate->getError()->__toString());
        }

        $update = [
            'state' => $data['state'],
        ];

        $where = [
            'id' => [$data['ids'],'in']
        ];

        $res = UserModel::updateData($update, $where);

        foreach ($data['ids'] as $id) {
            self::delCache($id);
        }

        return $this->success(['affected_rows'=>$res->lastQueryResult()->getAffectedRows()]);
    }

    /**
     * 审核通过
     * @param $data
     * @return Output
     * @throws DefaultException
     * @throws \EasySwoole\Validate\Exception\Runtime
     */
    public function approved($data) : Output{
        // 验证规则
        $rules = [
            'ids'        => 'required|notEmpty|isArray',
        ];

        // 验证字段的别名
        $alias = [
            'ids'        => '用户id',
        ];

        // 组装快速验证
        $validate = Validate::make($rules, [], $alias);

        // 验证结果
        $bool = $validate->validate($data);
        if (!$bool) {
            throw new DefaultException($validate->getError()->__toString());
        }

        $update = [
            'state' => UserModel::STATE_SUCCESS,
        ];

        $where = [
            'id'    => [$data['ids'], 'in'],
            'state' => UserModel::STATE_WAIT
        ];

        $res = UserModel::updateData($update, $where);

        foreach ($data['ids'] as $id) {
            self::delCache($id);
        }

        return $this->success(['affected_rows'=>$res->lastQueryResult()->getAffectedRows()]);
    }

    /**
     * 审核通过
     * @param $data
     * @return Output
     * @throws DefaultException
     * @throws \EasySwoole\Validate\Exception\Runtime
     */
    public function refuse($data) : Output{
        // 验证规则
        $rules = [
            'ids'         => 'required|notEmpty|isArray',
            'examine_msg' => 'required|notEmpty|mbLengthMax:255',
        ];

        // 验证字段的别名
        $alias = [
            'ids'         => '用户id',
            'examine_msg' => '审核内容',
        ];

        // 组装快速验证
        $validate = Validate::make($rules, [], $alias);

        // 验证结果
        $bool = $validate->validate($data);
        if (!$bool) {
            throw new DefaultException($validate->getError()->__toString());
        }

        $update = [
            'state'       => UserModel::STATE_FAIL,
            'examine_msg' => $data['examine_msg'],
        ];

        $where = [
            'id'    => [$data['ids'], 'in'],
            'state' => UserModel::STATE_WAIT
        ];

        $res = UserModel::updateData($update, $where);

        foreach ($data['ids'] as $id) {
            self::delCache($id);
        }

        return $this->success(['affected_rows'=>$res->lastQueryResult()->getAffectedRows()]);
    }

    /**
     * 重置密码
     * @param $data
     * @return Output
     * @throws DefaultException
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\Mysqli\Exception\Exception
     * @throws \EasySwoole\Validate\Exception\Runtime
     */
    public function resetPassword($data){
        // 组装快速验证
        $validate = Validate::make(['id' => 'required|notEmpty'], [], []);

        // 验证结果
        $bool = $validate->validate($data);
        if (!$bool) {
            throw new DefaultException($validate->getError()->__toString());
        }

        $password = Random::character(8);

        //初始化密码
        list($password, $salt) = (new UserService)->getPassword($password);


        //更新信息
        $userModel = new UserModel();
        $res = $userModel->resetPassword($data['id'], $password, $salt);

        if (!$res) {
            throw new DefaultException('更新密码失败！');
        }

        return $this->success(['password'=>$password]);
    }

    public function logList($params,$request){
        $column_cn_arr = [
            'id'              => 'id',
            'username'        => ['name' => '登陆用户'],
            'email'           => ['name' => '电子邮箱'],
            'name'            => ['name' => '姓名'],
            'phone'           => ['name' => '手机号'],
            'state'      => ['name' => '用户状态'],
            'avatar'          => ['name' => '头像'],
            'last_login_time' => ['name' => '最近登录时间'],
            'updated_by'      => ['name' => '更新操作员'],
            'created_by'      => ['name' => '创建人'],
        ];
        $form = new LogListForm($params, UserLogModel::class, $column_cn_arr, $request);
        return $form->lists();
    }
}
